package com.alinesno.cloud.common.web.login.dialect.processor;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IAttribute;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.spring5.context.SpringContextUtils;
import org.thymeleaf.standard.expression.Each;
import org.thymeleaf.standard.expression.EachUtils;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.util.StringUtils;

import com.alinesno.cloud.base.boot.entity.ManagerAccountEntity;
import com.alinesno.cloud.base.boot.service.IManagerResourceService;
import com.alinesno.cloud.common.web.login.dialect.enums.PermissionEachEnums;
import com.alinesno.cloud.common.web.login.session.CurrentAccountSession;

import cn.hutool.core.lang.Assert;

/**
 * 权限框可配置标签 
 * @author WeiXiaoJin
 * @since 2019年10月4日 下午5:12:59
 */
public final class PermissionEachAttrProcessor extends AbstractAttributeTagProcessor {

	private static final Logger log = LoggerFactory.getLogger(PermissionEachAttrProcessor.class) ; 
    public static final int PRECEDENCE = 300;
    public static final String ATTR_NAME = "permissionEach";

    public PermissionEachAttrProcessor(final TemplateMode templateMode, final String dialectPrefix) {
        super(templateMode, dialectPrefix, null, false, ATTR_NAME, true, PRECEDENCE, true);
    }

    @Override
    protected void doProcess(
            final ITemplateContext context,
            final IProcessableElementTag tag,
            final AttributeName attributeName, final String attributeValue,
            final IElementTagStructureHandler structureHandler) {

    	ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    	HttpServletRequest request = requestAttributes.getRequest();
    	
    	ApplicationContext ctx = SpringContextUtils.getApplicationContext(context);
    	ManagerAccountEntity account = ctx.getBean(CurrentAccountSession.class).get() ; 
    	IManagerResourceService managerResourceService = ctx.getBean(IManagerResourceService.class) ; 
    	
    	String menuId = request.getParameter("menuId") ; // 所属菜单
    	IAttribute type = tag.getAttribute("type") ;  // 权限类型(按钮/搜索框)
    	
    	Assert.isTrue(type != null && 
    			(PermissionEachEnums.BUTTOM.value.equals(type.getValue())
    			||PermissionEachEnums.SEARCH.value.equals(type.getValue())) , "权限类型不正常");
    	
    	log.debug("menuId:{} , type;{}" , menuId, type.getValue());  
    	log.debug("account:{} , managerResourceService:{}" , account , managerResourceService);
    	 
        final Each each = EachUtils.parseEach(context, attributeValue);

        final IStandardExpression iterVarExpr = each.getIterVar();
        final Object iterVarValue = iterVarExpr.execute(context);

        final IStandardExpression statusVarExpr = each.getStatusVar();
        final Object statusVarValue;
        if (statusVarExpr != null) {
            statusVarValue = statusVarExpr.execute(context);
        } else {
            statusVarValue = null; 
        }

        final IStandardExpression iterableExpr = each.getIterable();
        final Object iteratedValue = iterableExpr.execute(context);

        final String iterVarName = (iterVarValue == null? null : iterVarValue.toString());
        if (StringUtils.isEmptyOrWhitespace(iterVarName)) {
            throw new TemplateProcessingException("Iteration variable name expression evaluated as null: \"" + iterVarExpr + "\"");
        }

        final String statusVarName = (statusVarValue == null? null : statusVarValue.toString());
        if (statusVarExpr != null && StringUtils.isEmptyOrWhitespace(statusVarName)) {
            throw new TemplateProcessingException("Status variable name expression evaluated as null or empty: \"" + statusVarExpr + "\"");
        }

        structureHandler.iterateElement(iterVarName, statusVarName, iteratedValue);

    }
}
